package org.sunspotworld;

import com.sun.spot.sensorboard.EDemoBoard;
import com.sun.spot.sensorboard.peripheral.ISwitch;
import com.sun.spot.sensorboard.peripheral.ISwitchListener;
import com.sun.spot.sensorboard.peripheral.ITriColorLED;
import java.util.Random;

/**
 * Class Game
 * @author Geert Weening, Sebastian Nadorp, Daniel van Cleef
 */
class Game implements ISwitchListener, Protocoll {

    private Main main;
    // hardware from the SunSPOT
    private ITriColorLED[] leds = EDemoBoard.getInstance().getLEDs();
    private ISwitch leftSwitch = EDemoBoard.getInstance().getSwitches()[0];
    private ISwitch rightSwitch = EDemoBoard.getInstance().getSwitches()[1];
    private SensorThread sensorThread;
    private boolean hasPotato = false;
    private boolean gameStarted = false;
    private long endTime;
    private long mayThrowTime;
    private int score = 0;


    /**
     * Constructor 
     * @param aMain
     */
    public Game(Main main) {
        this.main = main;
        sensorThread = new SensorThread(main, this);

        if (main.getConnections().isEmpty()) {
            leds[0].setRGB(255, 0, 0);
            leds[7].setRGB(255, 0, 0);
        }

        leds[0].setOn();
        leds[7].setOn();
    }

    /**
     * check if endtime is reached
     * @return
     */
    public boolean isEndTime() {
        System.out.println(endTime +"\n" + System.currentTimeMillis() + "\n --------");
        return endTime >= System.currentTimeMillis();
    }

    /**
     * check if mayThrowtime is reached
     */
    public boolean isMayThrowTime() {
        return mayThrowTime <= System.currentTimeMillis();
    }

    /**
     * handles recieving of messages
     * @param message
     */
    public void receiveMessage(String message) {
        String[] parts = main.separateStrings(message);
        System.out.println("-- message recieved: " + message);
        if (parts[0].length() > 10) { //if a message is bigger dan 10 it's a potato, potatos can only be recieved when the game has started

            if(!gameStarted){
                System.out.println(message + " recieved while game was not started");
                System.out.println("starting game anyway");
                gameStarted();
            }

            endTime = Long.parseLong(parts[0]);
            hasPotato = true;
            mayThrowTime = generateMayThrowTime();
            display();
            sensorThread.run();
            
        } //other packages arrived!
        else {
            if (Integer.parseInt(parts[0]) == STARTGAME) {
                gameStarted();
            }
            if (Integer.parseInt(parts[0]) == DEADPLAYER) {
                resetForRound();
            }
        }
    }

    /**
     * sets the score one up
     */
    public void upScore() {
        score++;
    }

    /**
     * returns the score
     * @return score
     */
    public int getScore() {
        return score;
    }

    /**
     * sets the endTime
     * @param anEndTime
     */
    public void setEndTime(long anEndTime) {
        endTime = anEndTime;
    }

    /**
     * handles the fact when you lose a round
     */
    public void isOut() {
        System.out.println("i'm out");
        main.massMessage(DEADPLAYER + "");
        hasPotato = false;

        gameStarted = false;

        display();

        for (int i = 0; i <= 7; i++) {
            leds[i].setRGB(255, 0, 0);
            leds[i].setOn();
        }

        leds[0].setRGB(255, 0, 0);
        leds[7].setRGB(255, 0, 0);
        leds[0].setOn();
        leds[7].setOn();

//         main.idleAllConnections(); // should move all connections to idle and start waiting again for new connections

    }

    /**
     * generates an endtime
     * @return the timestamp from current time + time for a potato to end
     */
    public long generateEndTime() {
        Random r = new Random();
        int next = 0;

        //random between 30 en 90 bepalen
        while (next < 30) {
            next = r.nextInt(90);
        }

        next = next * 1000; //x 1000 to make seconds

        //ff om te testen 10 seconden
        next = 20 * 1000;
        return System.currentTimeMillis() + next;
    }

    /**
     * generates an mayThrowTime
     * @return the timestamp from current time + time for when to throw the potato
     */
    public long generateMayThrowTime() {

        //2 seconds to throw
        int next = 2 * 1000;
        return System.currentTimeMillis() +next;
    }

    /**
     * display to control the leds
     */
    public void display() {
        for (int i = 1; i <= 7; i++) {
            leds[i].setOff();
        }
        if (gameStarted) { //if the game is started and running the outside leds will be green
            leds[0].setRGB(0, 255, 0);
            leds[7].setRGB(0, 255, 0);
            leds[1].setOn();
            leds[7].setOn();
        }
        if (hasPotato) { // potato will be visible with 2 blue leds in the middle
            leds[3].setRGB(0, 0, 255);
            leds[4].setRGB(0, 0, 255);
            leds[3].setOn();
            leds[4].setOn();
        } else { // if the potato is gone, the leds will go off
            leds[3].setOff();
            leds[4].setOff();
        }
    }

    /**
     * prepares the spot so a game can be started
     * @require more than 1 other spot connected
     */
    public void prepareForGame() {
        leftSwitch.addISwitchListener(this); //add listeners so a game can be started by button
        rightSwitch.addISwitchListener(this);

        leds[0].setRGB(0, 0, 255); // outside leds will be Blue when waiting for a game
        leds[7].setRGB(0, 0, 255);
    }

    /**
     * begins a game, this Spot has started
     */
    public void beginGame() {

        endTime = generateEndTime(); //set endTime

        hasPotato = true; //this spot will have the potato since this spot started the game
        
        main.massMessage(STARTGAME + ""); //let other spots know the game has started

        gameStarted = true;
        
        
        leftSwitch.removeISwitchListener(this); //remove listeners once game is started
        rightSwitch.removeISwitchListener(this);

        leds[0].setRGB(0, 0, 255);
        leds[7].setRGB(0, 0, 255);
        display();
        sensorThread.run();
        System.out.println("begin game started");
    }

    /**
     * If another Spot has started the game, this sets this spot to the right status
     */
    public void gameStarted() {
        leftSwitch.removeISwitchListener(this); // remove listeners once game is started
        rightSwitch.removeISwitchListener(this);

        display();

        leds[0].setRGB(0, 255, 0); //Set leds to green to see that the game has started
        leds[7].setRGB(0, 255, 0);

        gameStarted = true;

        System.out.println("game started");
    }

    /**
     * Listener for switch pressed
     * @param sw
     */
    public void switchPressed(ISwitch sw) {
        int switchNum = (sw == leftSwitch) ? 1 : 2;
        System.out.println("Switch " + switchNum + " closed.");

        if(switchNum == 1) {
            beginGame();
        } else if(switchNum == 2) {
            System.out.println("Broadcasting uit!!!!");
            main.setBroadcasting(false);
        }

    }

    /**
     * Listener for switch released
     * @param sw
     */
    public void switchReleased(ISwitch sw) {
        int switchNum = (sw == leftSwitch) ? 1 : 2;
        System.out.println("Switch " + switchNum + " opened.");
    }

    /**
     * When a round is run and a spot is out this function will prepare for the next round
     */
    public void resetForRound() {
        if (main.getConnections().isEmpty()) { // if you're the only spot left you're obviously the winner of the game
            for (int i = 0; i <= 7; i++) {
                leds[i].setRGB(255, 255, 255);
                leds[i].setOn();
            }
            leds[0].setRGB(255, 0, 0);
            leds[7].setRGB(255, 0, 0);

            System.out.println("i'm the winner!");

            upScore(); // up your score because you have won

        // should check connections from idleConnections and add them as new connections
        // should send broadcast or massmessage to all previous connections to tell there's a new game to be started
        // main.resetForNewGame();
        } else {
            System.out.println("preparing for next round");

            leftSwitch.addISwitchListener(this); //add the switches again so you can press to begin a new round
            rightSwitch.addISwitchListener(this);

            leds[0].setRGB(0, 255, 0); //set leds so you can see a round has ended and you can start a new one
            leds[1].setRGB(0, 0, 255);
            leds[2].setRGB(0, 0, 255);
            leds[5].setRGB(0, 0, 255);
            leds[6].setRGB(0, 0, 255);
            leds[7].setRGB(0, 255, 0);
            leds[1].setOn();
            leds[2].setOn();
            leds[5].setOn();
            leds[6].setOn();
        }

    }

    /**
     * Sets the leds for each connection
     */
    public void setConnectLed() {
        int i = main.getConnections().size(); //get size of connections
        for (int j = i; i < 8; i++) { // put the amount of leds as many as connections are to green
            leds[j].setRGB(0, 255, 0);
            leds[j].setOn();

        }
    }

     public void setPotatoe(boolean potatoe){
        hasPotato = potatoe;
    }

     public boolean getHasPotatoe(){
         return hasPotato;
     }

    public long getEndTime(){
        return endTime;
    }
}
